#ifndef FEDOM_H
#define FEDOM_H
#include "fecore_global.h"
#include <QString>
#include <QSize>
#include <QVariant>
#include <QList>
#include "feactualdata.h"

class FeDOMNode;
class FeDOMProperty;
class FeDOMSignalBind;
class FeDOMSignalBinding;
class FeDOMLayoutItem;
class FeDOMWidget;
class FeDOMLayout;
class FeDOMVBoxLayout;
class FeDOMHBoxLayout;
class FeDOMScaleLayout;
class FeDOMDocument;

class FECORE_EXPORT FeDOMNode {
public:
	enum NodeType
	{
		Node = 0,
		Property,
		SignalBind,
		SignalBinding,
		LayoutItem,
        Widget,
		Layout,
		HBoxLayout,
		VBoxLayout,
		ScaleLayout,
		Screen,
		Document
	};

	FeDOMNode();
	FeDOMNode(const FeDOMNode &);
	virtual ~FeDOMNode();

	bool isNull() const;
	NodeType nodeType() const;


	FeDOMDocument document() const;
	bool isInSameDocument(const FeDOMNode &) const;

	FeDOMNode &operator=(const FeDOMNode &);

protected:
	friend class FeDOMDocument;
	friend FECORE_EXPORT bool operator==(const FeDOMNode &, const FeDOMNode &);
	void *d;
};

FECORE_EXPORT bool operator==(const FeDOMNode &, const FeDOMNode &);

class FECORE_EXPORT FeDOMProperty: public FeDOMNode {
public:
	FeDOMProperty();
	FeDOMProperty(const FeDOMProperty &);

	QString name() const;
	void setName(const QString &);

	QVariant value() const;
	void setValue(const QVariant &);

	FeDOMProperty &operator=(const FeDOMProperty &);

protected:
	friend class FeDOMDocument;
};

class FECORE_EXPORT FeDOMSignalBind: public FeDOMNode {
public:
	FeDOMSignalBind();
	FeDOMSignalBind(const FeDOMSignalBind &);

	FeActualDataId signalId() const;
	void setSignalId(const FeActualDataId &);

	QString widgetName() const;
	void setWidgetName(const QString &);

	QString propertyName() const;
	void setPropertyName(const QString &);

	FeDOMSignalBind &operator=(const FeDOMSignalBind &);
	
protected:
	friend class FeDOMDocument;
};

class FECORE_EXPORT FeDOMSignalBinding: public FeDOMNode {
public:
	FeDOMSignalBinding();
	FeDOMSignalBinding(const FeDOMSignalBinding &);

	QList<FeDOMSignalBind> bindings() const;
	void add(const FeDOMSignalBind &);

	FeDOMSignalBinding &operator=(const FeDOMSignalBinding &);

protected:
	friend class FeDOMDocument;
};

class FECORE_EXPORT FeDOMLayoutItem: public FeDOMNode {
public:
	FeDOMLayoutItem();
	FeDOMLayoutItem(const FeDOMLayoutItem &);
	FeDOMLayoutItem &operator=(const FeDOMLayoutItem &);

protected:
	friend class FeDOMDocument;
};

class FECORE_EXPORT FeDOMWidget: public FeDOMLayoutItem {
public:
	FeDOMWidget();
	FeDOMWidget(const FeDOMWidget &);

	QString name() const;
	void setName(const QString &);

	QString type() const;
	void setType(const QString &);

	QList<FeDOMProperty> properties() const;
	FeDOMProperty getProperty(const QString &name) const;
	void addProperty(const FeDOMProperty &);
	void removeProperty(const FeDOMProperty &);

	FeDOMWidget &operator=(const FeDOMWidget &);

protected:
	friend class FeDOMDocument;
};

class FECORE_EXPORT FeDOMLayout: public FeDOMLayoutItem {
public:
	FeDOMLayout();
	FeDOMLayout(const FeDOMLayout &);

	QList<FeDOMLayoutItem> items() const;
	void addItem(const FeDOMLayoutItem &);
	void removeItem(const FeDOMHBoxLayout &);

	FeDOMLayout &operator=(const FeDOMLayout &);

private:
	friend class FeDOMDocument;
	
};

class FECORE_EXPORT FeDOMVBoxLayout: public FeDOMLayout {
public:
	FeDOMVBoxLayout();
	FeDOMVBoxLayout(const FeDOMVBoxLayout &);

	int margin() const;
	void setMargin(int);

	int spacing() const;
	void setSpacing(int);

	FeDOMVBoxLayout &operator=(const FeDOMVBoxLayout &);

private:
	friend class FeDOMDocument;
};

class FECORE_EXPORT FeDOMHBoxLayout: public FeDOMLayout {
public:
	FeDOMHBoxLayout();
	FeDOMHBoxLayout(const FeDOMHBoxLayout &);
	
	int margin() const;
	void setMargin(int);

	int spacing() const;
	void setSpacing(int);

	virtual FeDOMHBoxLayout &operator=(const FeDOMHBoxLayout &);

private:
	friend class FeDOMDocument;
};

class FECORE_EXPORT FeDOMScaleLayout: public FeDOMLayout {
public:
	FeDOMScaleLayout();
	FeDOMScaleLayout(const FeDOMScaleLayout &);

	QSize size() const;
	void setSize(const QSize &);

	FeDOMScaleLayout &operator=(const FeDOMScaleLayout &);

private:
	friend class FeDOMDocument;
};

class FECORE_EXPORT FeDOMScreen: public FeDOMNode {
public:
	FeDOMScreen();
	FeDOMScreen(const FeDOMScreen &);

	QList<FeDOMProperty> properties() const;
	FeDOMProperty getProperty(const QString &name) const;
	void addProperty(const FeDOMProperty &);
	void removeProperty(const FeDOMProperty &);

	FeDOMLayout layout() const;
	void setLayout(const FeDOMLayout &);

	FeDOMSignalBinding signalBinding() const;
	void setSignalBinding(const FeDOMSignalBinding &);

	FeDOMScreen &operator=(const FeDOMScreen &);

private:
	friend class FeDOMDocument;
};


class FECORE_EXPORT FeDOMDocument: public FeDOMNode {
public:
	FeDOMDocument();
	FeDOMDocument(const FeDOMDocument &);

	FeDOMProperty createProperty(const QString &name, const QVariant &value);
	FeDOMSignalBind createSignalBind(const FeActualDataId &signal, const QString &widget, const QString &property);
	FeDOMSignalBinding createSignalBinding();
	FeDOMWidget createWidget(const QString &name, const QString &type);
	FeDOMHBoxLayout createHBoxLayout(int margin=0, int spacing=0);
	FeDOMVBoxLayout createVBoxLayout(int margin=0, int spacing=0);
	FeDOMScaleLayout createScaleLayout(const QSize &size);
	FeDOMScreen createScreen();

	FeDOMScreen screen() const;
	void setScreen(const FeDOMScreen &);

	FeDOMDocument &operator=(const FeDOMDocument &);

private:
	friend class FeDOMNode;
	FeDOMDocument(void *);

};


#endif // FEDOM_H